package com.cms.clash.service.impl;

import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cms.clash.dto.ArcQueryDTO;
import com.cms.clash.dto.ArcShowDTO;
import com.cms.clash.dto.FlagEnum;
import com.cms.clash.entity.ArchiveContentEntity;
import com.cms.clash.entity.ArchiveEntity;
import com.cms.clash.entity.ArchiveTypeEntity;
import com.cms.clash.mapper.ArchiveContentMapper;
import com.cms.clash.mapper.ArchiveMapper;
import com.cms.clash.service.IArchiveService;
import com.cms.clash.util.TemplateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 文档主表-实现类
 * @author cms
 * @since 2024-07-27
 */
@Service
public class ArchiveService extends ServiceImpl<ArchiveMapper, ArchiveEntity> implements IArchiveService {

    @Autowired
    private ArchiveTypeService typeService;

    @Autowired
    private ArchiveContentMapper archiveContentMapper;

    /**
     * 根据flag属性获取一个文档
     * @return
     */
    public ArcShowDTO getArcByFlag(String flag, String typeId) {
        List<ArcShowDTO> list = getArcList(0, 1, flag, null);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        return convertArcEntity(list.get(0));
    }

    /**
     * 根据flag属性获取文档列表
     * @return
     */
    public List<ArcShowDTO> getArcList(Integer typeId, Integer limitNum, String flag, String orderBy) {
        ArcQueryDTO dto = new ArcQueryDTO();
        dto.setTypeId(typeId);
        dto.setFlag(flag);
        dto.setLimitNum(limitNum);
        dto.setOrderBy(orderBy);
        List<ArcShowDTO> entityList = queryArcListSearch(dto);
        return entityList;
    }

    /**
     * 查询文章总数
     * @param typeId
     * @param flag
     * @param keyWord
     * @return
     */
    public Integer queryArcListSearchCount(Integer typeId, String flag, String keyWord) {
        LambdaQueryWrapper<ArchiveEntity> wrapper = new LambdaQueryWrapper<>();
        if (null != typeId && typeId > 0) {
            wrapper.eq(ArchiveEntity::getTypeId, typeId);
        }
        if (StringUtils.isNotEmpty(keyWord)) {
            wrapper.like(ArchiveEntity::getTitle, keyWord);
        }
        boolean flagIsExist = FlagEnum.checkFlagIsExist(flag);
        if (flagIsExist) {
            wrapper.last(" and " + flag + " = 1 ");
        }
        int total = this.baseMapper.selectCount(wrapper).intValue();
        return total;
    }


    /**
     * 搜索文章列表
     * @param dto
     * @return
     */
    public List<ArcShowDTO> queryArcListSearch(ArcQueryDTO dto) {
        // Integer typeId,String flag, Integer pageSize, Integer currentPage, String kw,Integer limitNum, String orderBy
        Integer pageSize = (null != dto.getPageSize() && dto.getPageSize() > 0) ? dto.getPageSize() : 10;
        Integer currPage = (null != dto.getPageIndex() && dto.getPageIndex() > 0) ? dto.getPageIndex() : 1;
        Integer limitNum = (null != dto.getLimitNum() && dto.getLimitNum() > 0) ? dto.getLimitNum() : 0;

        // 构建查询
        LambdaQueryWrapper<ArchiveEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ArchiveEntity::getStatus, 1);
        if (null != dto.getTypeId() && dto.getTypeId() > 0) {
            wrapper.eq(ArchiveEntity::getTypeId, dto.getTypeId());
        }
        if (StringUtils.isNotEmpty(dto.getKeyWord())) {
            wrapper.like(ArchiveEntity::getTitle, dto.getKeyWord());
        }
        boolean flagIsExist = FlagEnum.checkFlagIsExist(dto.getFlag());
        if (flagIsExist) {
            wrapper.last(" and " + dto.getFlag() + " = 1 ");
        }
        if (StringUtils.isNotEmpty(dto.getOrderBy())) {
            wrapper.last(" order by " + dto.getOrderBy() + " ");
        }

        // limit优先级大于分页
        String limitStr = (limitNum > 0) ? (" limit " + limitNum) : (" limit " + (currPage - 1) * pageSize + "," + pageSize);
        wrapper.last(limitStr);
        List<ArchiveEntity> list = this.baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        ArrayList<ArcShowDTO> resultList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (ArchiveEntity entity : list) {
                resultList.add(convertArcEntity(entity));
            }
        }
        return resultList;
    }

    /**
     * 根据uuid获取文档详情
     * @param uuid
     * @return
     */
    public ArcShowDTO queryArcByUuid(String uuid) {
        if (StringUtils.isEmpty(uuid)) {
            return null;
        }
        LambdaQueryWrapper<ArchiveEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ArchiveEntity::getUuid, uuid);
        ArchiveEntity entity = this.baseMapper.selectOne(wrapper);
        if (null == entity) {
            return null;
        }
        ArcShowDTO dto = convertArcEntity(entity);
        if (StringUtils.isEmpty(dto.getContent())) {
            dto.setContent("");
        }
        // 详情内容
        LambdaQueryWrapper<ArchiveContentEntity> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(ArchiveContentEntity::getAid, entity.getAid());
        ArchiveContentEntity entity2 = archiveContentMapper.selectOne(wrapper2);
        if (null !=entity2){
            dto.setContent(HtmlUtil.unescape(entity2.getContent()));
        }
        return dto;
    }

    /**
     * 获取上一条下一条
     * @param aid
     * @param typeId
     * @return
     */
    public Map<String, ArcShowDTO> queryArcPrevAndNext(Integer aid, Integer typeId) {
        HashMap<String, ArcShowDTO> map = new HashMap<>();
        LambdaQueryWrapper<ArchiveEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.lt(ArchiveEntity::getAid, aid);
        wrapper.last("limit 1");
        ArchiveEntity entityPrev = this.baseMapper.selectOne(wrapper);
        if (ObjectUtils.isNotEmpty(entityPrev)) {
            ArcShowDTO dtoPrev = convertArcEntity(entityPrev);
            map.put("prev", dtoPrev);
        }

        wrapper.clear();
        wrapper.gt(ArchiveEntity::getAid, aid);
        wrapper.last("limit 1");
        ArchiveEntity entityNext = this.baseMapper.selectOne(wrapper);
        if (ObjectUtils.isNotEmpty(entityNext)) {
            ArcShowDTO dtoNext = convertArcEntity(entityNext);
            map.put("next", dtoNext);
        }
        return map;
    }

    /**
     * 转换单个文章
     * @param entity
     * @return
     */
    private ArcShowDTO convertArcEntity(ArchiveEntity entity) {
        if (null != entity) {
            return convertArcEntity(Arrays.asList(entity)).get(0);
        }
        return null;
    }

    /**
     * 转换文章的扩展字段
     * @param entityList
     * @return
     */
    private List<ArcShowDTO> convertArcEntity(List<ArchiveEntity> entityList) {
        List<ArcShowDTO> newList = new ArrayList<>();
        Map<Integer, ArchiveTypeEntity> allNavMap = typeService.getAllNavMap();
        for (ArchiveEntity entity : entityList) {
            String formattedDate = TemplateUtil.tenTimeToString(entity.getCreateTime().longValue());
            ArchiveTypeEntity typeEntity = allNavMap.get("k" + entity.getTypeId());
            String typeLink = typeEntity.getTypeLink();
            String typeName = typeEntity.getTypeName();
            String link = "/info/" + entity.getUuid() + ".html";

            ArcShowDTO dto = new ArcShowDTO();
            BeanUtils.copyProperties(entity, dto);
            dto.setTypeName(typeName);
            dto.setTypeLink(typeLink);
            dto.setLink(link);
            dto.setCreateTimeFormat(formattedDate);
            newList.add(dto);
        }
        return newList;
    }

}
